package com.zoho.model_project.utils;

import org.apache.commons.lang.StringUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

public class DateUtil {

    public static final SimpleDateFormat FORMAT_DATE = new SimpleDateFormat("yyyy-MM-dd");
    public static final SimpleDateFormat FORMAT_DATE_WORD = new SimpleDateFormat("yyyy年MM月dd日");
    public static final SimpleDateFormat FORMAT_SECOND = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    public static final SimpleDateFormat FORMAT_MILLISECOND = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");

    public static final String DATE_FORMAT = "yyyy-MM-dd";
    public static final String YEAR_S_MONTH = "yyyy-MM";
    public static final String YEAR_MONTH = "yyyyMM";
    public static final String TIMEF_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String TIME_FORMAT = "yyyy-MM-dd HH:mm";

    // String类型的日期转换为 YYYY-mm-dd
    public static String parseDate(String date) {
        Date date1 = stringParseDate(date);
        return dateParseString(date1);
    }

    // String类型的日期转换为 YYYY年mm月dd日
    public static String parseDateWord(String date) {
        Date date1 = stringParseDate(date);
        return dateParseStringWord(date1);
    }

    // String转Date
    public static Date stringParseDate(String str) {
        Date date = null;
        try {
            date = FORMAT_DATE.parse(str);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return date;
    }

    // Date转String
    public static String dateParseString(Date date) {
        return FORMAT_DATE.format(date);
    }

    // Date转String
    public static String dateParseStringWord(Date date) {
        return FORMAT_DATE_WORD.format(date);
    }

    /**
     *     * 日期格式化
     *     *
     *     * @param pattern pattern
     *     * @param date 日期
     *
     * @return 格式化后的字符串
     *     
     */
    public static String dateFormat(String pattern, Date date) {
        if (date == null || StringUtils.isEmpty(pattern)) {
            return "";
        }
        try {
            LocalDateTime localDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
            return localDateTime.format(DateTimeFormatter.ofPattern(pattern));
        } catch (Exception e) {
            return "";
        }
    }

    /**
     * 将日期转换为日历
     *
     * @param date 日期
     * @return 日历
     */

    private static Calendar convert(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar;
    }

    /**
     * 返回当月最后一天的日期 返回String
     */
    public static String getLastDayOfMonth(Date date) {
        Calendar calendar = convert(date);
        calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DATE));
        DateFormat format = new SimpleDateFormat(DATE_FORMAT);
        return format.format(calendar.getTime());
    }

    /**
     * 获取当月第一天  返回格式例  2016-06-01
     *
     * @param date
     * @return
     * @author: 黄泽亮
     */

    public static String getFirstDayOfMonth(Date date) {
        Calendar calendar = convert(date);
        calendar.set(Calendar.DATE, calendar.getMinimum(Calendar.DATE));
        DateFormat format = new SimpleDateFormat(DATE_FORMAT);
        return format.format(calendar.getTime());
    }

    /**
     * 比较指定两日期,如果dateStr1早，dateStr2晚，返回true
     *
     * @param dateStr1 指定日期         2020-01-01
     * @param dateStr2 指定日期         2022-01-01
     * @param pattern  指定日期的格式
     * @return boolean  true
     */

    public static boolean dateCompare(String dateStr1, String dateStr2, String pattern) {

        boolean bea = false;
        SimpleDateFormat sdf_d = new SimpleDateFormat(pattern);
        Date date1;
        Date date0;
        try {
            date1 = sdf_d.parse(dateStr1);
            date0 = sdf_d.parse(dateStr2);
            bea = date0.after(date1);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return bea;
    }

    /**
     * 比较指定两日期,如果dateStr1早，dateStr2晚，返回true
     *
     * @param dateStr1 指定日期         2020-01-01
     * @param dateStr2 指定日期         2022-01-01
     * @return boolean  true
     */

    public static boolean dateCompare(String dateStr1, String dateStr2) {
        String fmt = "yyyy-MM-dd HH:mm:ss";
        dateStr1 = dateStr1.replace("T", " ");
        dateStr2 = dateStr2.replace("T", " ");
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(fmt);
        return dateCompare(dateStr1, dateStr2, fmt);
    }

    public static boolean appendYearMonth(String year, String month, String startTime, String endTime) {
        // 拼接时间 为 年月10号
        String time = year + "-" + month + "-" + "10";
        boolean boo1 = dateCompare(startTime, time, DATE_FORMAT);
        boolean boo2 = dateCompare(time, endTime, DATE_FORMAT);
        return boo1 && boo2;
    }

    /**
     * 获取今天的日期，格式如：2006-11-09
     *
     * @return String - 返回今天的日期
     */

    public static String getToday() {

        Calendar now = Calendar.getInstance(TimeZone.getDefault());
        SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
        sdf.setTimeZone(TimeZone.getDefault());
        return (sdf.format(now.getTime()));
    }

    /**
     * 获取今天的日期，格式如：2006-11-09 00:00:00
     *
     * @return String - 返回今天的日期
     */
    public static String getTodayHMS() {

        Calendar now = Calendar.getInstance(TimeZone.getDefault());
        SimpleDateFormat sdf = new SimpleDateFormat(TIMEF_FORMAT);
        sdf.setTimeZone(TimeZone.getDefault());
        return (sdf.format(now.getTime()));
    }

    /**
     * 获取今天的日期，带T，精确到 时分，秒默认是00，格式如：2023-03-20T10:55:00+08:00
     *
     * @return String - 返回今天的日期
     */
    public static String getTodayHMByT() {

        Calendar now = Calendar.getInstance(TimeZone.getDefault());
        SimpleDateFormat sdf = new SimpleDateFormat(TIME_FORMAT);
        sdf.setTimeZone(TimeZone.getDefault());
        String format = sdf.format(now.getTime());
        String replace = format.replace(" ", "T");
        return replace.concat(":00+08:00");
    }

    /**
     * 计算两个日期相差天数
     *
     * @param smdate
     * @param bdate
     * @return
     * @throws ParseException
     */

    public static int daysBetween(String smdate, String bdate) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        try {

            Calendar cal = Calendar.getInstance();

            cal.setTime(sdf.parse(smdate));

            long time1 = cal.getTimeInMillis();

            cal.setTime(sdf.parse(bdate));

            long time2 = cal.getTimeInMillis();

            long between_days = (time2 - time1) / (1000 * 3600 * 24);

            return Integer.parseInt(String.valueOf(between_days));

        } catch (ParseException ex) {

            ex.printStackTrace();

        }

        return 0;

    }

    /**
     * 返回指定日期的 年
     *
     * @param date 指定日期
     */
    public static String getYearByDate(Date date) {
        Calendar now = Calendar.getInstance();
        now.setTime(date);
        String HYPHEN_YEAR_MONTH_DAY = "yyyy";
        SimpleDateFormat sdf = new SimpleDateFormat(HYPHEN_YEAR_MONTH_DAY);
        return (sdf.format(now.getTime()));
    }

    /**
     * 返回指定日期的 月
     *
     * @param date 指定日期
     */
    public static String getMonthByDate(Date date) {
        Calendar now = Calendar.getInstance(TimeZone.getDefault());
        String HYPHEN_YEAR_MONTH_DAY = "MM";
        SimpleDateFormat sdf = new SimpleDateFormat(HYPHEN_YEAR_MONTH_DAY);
        return sdf.format(now.getTime());
    }

    /**
     * 返回指定日期的 日
     *
     * @param date 指定日期
     */
    public static String getDayByDate(Date date) {
        Calendar now = Calendar.getInstance(TimeZone.getDefault());
        String HYPHEN_YEAR_MONTH_DAY = "dd";
        SimpleDateFormat sdf = new SimpleDateFormat(HYPHEN_YEAR_MONTH_DAY);
        return sdf.format(now.getTime());
    }

    /**
     * 获取前两个月的日期
     *
     * @return String - 返回今天的日期
     */
    public static String getTwoMonthAgoDay() {
        // 获取当前日期
        LocalDate today = LocalDate.now();
        // 获取两个月前的日期
        LocalDate twoMonthsAgo = today.minus(Period.ofMonths(2));
        return twoMonthsAgo.toString();
    }

    // 获取30天以前的日期
    public static String getPrevious30DaysDate() {
        DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        // 获取当前日期
        LocalDate currentDate = LocalDate.now();
        // 计算前30天的日期
        LocalDate previous30DaysDate = currentDate.minusDays(30);
        // 将LocalDate格式化为字符串
        return previous30DaysDate.format(DATE_FORMATTER);
    }

    // 获取7天以前的日期
    public static String getPrevious7DaysDate() {
        DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        // 获取当前日期
        LocalDate currentDate = LocalDate.now();
        // 计算前7天的日期
        LocalDate previous30DaysDate = currentDate.minusDays(7);
        // 将LocalDate格式化为字符串
        return previous30DaysDate.format(DATE_FORMATTER);
    }

    // 获取15天以前的日期
    public static String getPrevious15DaysDate() {
        DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        // 获取当前日期
        LocalDate currentDate = LocalDate.now();
        // 计算前15天的日期
        LocalDate previous30DaysDate = currentDate.minusDays(15);
        // 将LocalDate格式化为字符串
        return previous30DaysDate.format(DATE_FORMATTER);
    }

    // 将时间戳转换为年月日
    public static String timestampToDate(long timestamp) {
        Instant instant = Instant.ofEpochMilli(timestamp);
        // 转换为系统默认时区的本地日期时间
        LocalDateTime localDateTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime();
        // 格式化模式为年月日
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        return localDateTime.format(formatter);
    }

    // 将时间戳转换为年月日时分秒
    public static String timestampToDateTime(long timestamp) {
        Instant instant = Instant.ofEpochMilli(timestamp);
        // 转换为系统默认时区的本地日期时间
        LocalDateTime localDateTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime();
        // 格式化模式包含时分秒
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return localDateTime.format(formatter);
    }

    // 处理带斜杠得日期,时间保留到时分秒
    public String formatSpecialTime(String time) {
        if (StringUtils.isBlank(time)) {
            return "";
        }
        SimpleDateFormat inputFormat;
        int i = time.indexOf(" ");

        if (time.contains("-")) {
            if(i>=10){
                inputFormat = new SimpleDateFormat("yyyy-MM-dd H:mm:ss");
            }else{
                inputFormat = new SimpleDateFormat("yyyy-M-d H:mm:ss");
            }
        } else if (time.contains("/")) {
            inputFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        } else {
            inputFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        }
        SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date date = inputFormat.parse(time);
            return outputFormat.format(date);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    // 处理带斜杠得日期,时间保留到时分秒，带T的格式
    public String formatSpecialTimeByT(String time) {
        if (StringUtils.isBlank(time)) {
            return "";
        }
        // 定义原始日期时间的格式，将 HH 改为 H 以匹配一位或两位小时数
        DateTimeFormatter inputFormatter;
        if (time.contains("-")) {
            inputFormatter = DateTimeFormatter.ofPattern("yyyy-M-d H:mm:ss");
        } else if (time.contains("/")) {
            inputFormatter = DateTimeFormatter.ofPattern("yyyy/M/d H:mm:ss");
        } else {
            inputFormatter = DateTimeFormatter.ofPattern("yyyy/M/d H:mm:ss");
        }
        // 将原始日期时间字符串解析为 LocalDateTime 对象
        LocalDateTime localDateTime = LocalDateTime.parse(time, inputFormatter);
        // 将 LocalDateTime 对象转换为带时区偏移的 OffsetDateTime 对象，这里使用 +08:00 时区
        OffsetDateTime offsetDateTime = localDateTime.atOffset(ZoneOffset.of("+08:00"));
        // 定义目标日期时间的格式
        DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX");
        // 将 OffsetDateTime 对象格式化为目标字符串
        return offsetDateTime.format(outputFormatter);
    }
}
